import { contextMenu, splitterPaneContextMenu } from './context-menu-config';
import { cloneDeep } from 'lodash-es';
import { RowNode } from '@farris/ui-treetable';
import { ContextMenuManager } from '../../../../service/context-menu.manager';
import { ControlContextMenuItem } from '../../../../entity/control-context-menu';
import { ComponentSchema } from '@farris/designer-element';
import { FarrisDesignBaseComponent } from '@farris/designer-element';
import { ControlTreeNode } from '@farris/designer-devkit';
import { DgControl } from '../../../../utils/dg-control';
import { CreateDetailContainerService } from './services/create-detail-container.service';
import { ControlService } from '../../../../service/control.service';
import { ChildContainerFillService } from '../../content-container/context-menu/services/child-container-fill';


/** 添加从表区域命令 */
export const CREATE_DETAIL_CONTAINER_COMMAND = 'createDetailContainer';

/** 添加从从表区域命令 */
export const CREATE_GRAND_CONTAINER_COMMAND = 'createGrandContainer';

/** 修改面板分配比例命令 */
export const SPLITTER_PANE_PROPORTION = 'paneProportion';

/** 修改面板布局方向命令 */
export const SPLITTER_PANE_DIRECTION = 'paneDirection';
export const SPLITTER_PANE_DIRECTION_HORIZONTAL = 'horizontal';
export const SPLITTER_PANE_DIRECTION_VERTICAL = 'vertical';
const CHILD_FILL_COMMAND = 'childContainerFill';


export class SplitterContextMenuManager extends ContextMenuManager {

    private parentRowNode: RowNode;

    constructor(cmp: FarrisDesignBaseComponent, rowNode: RowNode, parentRowNode: RowNode) {
        super(cmp, rowNode);
        this.parentRowNode = parentRowNode;

    }
    /**
     * 过滤、修改控件树右键菜单
     */
    setContextMenuConfig() {
        let menuConfig = cloneDeep(contextMenu) as ControlContextMenuItem[];

        const parentTreeNode = this.parentRowNode && this.parentRowNode.node as ControlTreeNode;
        if (parentTreeNode && parentTreeNode.rawElement.type === DgControl.Splitter.type) {
            menuConfig = cloneDeep(splitterPaneContextMenu) as ControlContextMenuItem[];
        }

        if (!menuConfig) {
            return [];
        }

        menuConfig = this.assemblePaneProportionMenu(this.cmpInstance.component, menuConfig);
        menuConfig = this.assemblePaneDirectionMenu(this.cmpInstance.component, menuConfig);
        menuConfig = this.assembleCreateChildContainerMenu(this.rowNode.node.id, menuConfig);
        menuConfig = this.assembleChildFillMenu(this.rowNode.node.id, menuConfig);

        // 配置菜单点击事件
        this.addContextMenuHandle(menuConfig);

        return menuConfig;
    }
    /**
     * 点击控件树右键菜单
     */
    contextMenuClicked(e: { data: RowNode, menu: ControlContextMenuItem }) {

        const menu = e.menu;

        switch (menu.parentMenuId) {
            // 修改布局比例
            case SPLITTER_PANE_PROPORTION: {
                this.setPaneProportion(this.cmpInstance.component, menu.title);
                return;
            }
            // 修改布局方向
            case SPLITTER_PANE_DIRECTION: {
                this.setPaneDirection(this.cmpInstance.component, menu.id);
                return;
            }
        }

        switch (menu.id) {
            // 添加从表区域
            case CREATE_DETAIL_CONTAINER_COMMAND: {
                this.createDetailContainer();
                return;
            }
            // 添加从从表区域
            case CREATE_GRAND_CONTAINER_COMMAND: {
                this.createGrandContainer();
                return;
            }
            // 启用从表填充
            case 'enable' + CHILD_FILL_COMMAND: {
                this.enableChildContainerFill(e.data.id);
                return;
            }
            // 关闭从表填充
            case 'close' + CHILD_FILL_COMMAND: {
                this.closeChildContainerFill(e.data.id);
                return;
            }
        }
        this.notifyService.warning('暂不支持');
    }

    /**
     * 限制分配比例菜单的使用范围
     * @param splitterId 当前分隔组件id
     * @param menuConfig 菜单配置
     */
    private assemblePaneProportionMenu(splitterDocument: ComponentSchema, menuConfig: ControlContextMenuItem[]) {

        // 目前只支持两个面板的分隔组件
        if (!splitterDocument.contents || splitterDocument.contents.length !== 2) {
            // console.log('只支持包含2个分隔区域的面板启用分配比例菜单');
            menuConfig = menuConfig.filter(menu => menu.id !== SPLITTER_PANE_PROPORTION);
            return menuConfig;
        }
        // 限制可修改的范围
        // tslint:disable-next-line:max-line-length
        if (!splitterDocument.appearance || !splitterDocument.appearance.class || !splitterDocument.appearance.class.includes('f-page-content')) {
            // console.log('分隔组件必须包含f-page-content样式才能启用分配比例菜单');
            menuConfig = menuConfig.filter(menu => menu.id !== SPLITTER_PANE_PROPORTION);
            return menuConfig;
        }

        const leftSplitterPane = splitterDocument.contents[0];
        // tslint:disable-next-line:max-line-length
        if (!leftSplitterPane.appearance || !leftSplitterPane.appearance.class || !leftSplitterPane.appearance.class.includes('f-page-content-nav')) {
            // console.log('左侧分隔区域必须包含f-page-content-nav样式才能启用分配比例菜单');
            menuConfig = menuConfig.filter(menu => menu.id !== SPLITTER_PANE_PROPORTION);
            return menuConfig;
        }
        const rightSplitterPane = splitterDocument.contents[1];
        // tslint:disable-next-line:max-line-length
        if (!rightSplitterPane.appearance || !rightSplitterPane.appearance.class || !rightSplitterPane.appearance.class.includes('f-page-content-main')) {
            // console.log('右侧分隔组件必须包含f-page-content-main样式才能启用分配比例菜单');
            menuConfig = menuConfig.filter(menu => menu.id !== SPLITTER_PANE_PROPORTION);
            return menuConfig;
        }

        return menuConfig;
    }

    /**
     * 根据点击的菜单修改左右两侧面板的分配比例
     * @param splitterId 当前分隔组件id
     * @param command 比例菜单的command id
     */
    private setPaneProportion(splitterDocument: ComponentSchema, command: string) {

        const leftSplitterPane = splitterDocument.contents[0];
        const rightSplitterPane = splitterDocument.contents[1];

        // 判断当前布局方向
        const direction = splitterDocument.appearance.class.includes('flex-column') ? 'vertical' : 'horizontal';
        const defaultClass = direction === 'horizontal' ? 'f-col-w' : 'f-col-h';

        // 修改左侧区域的col样式
        switch (command) {
            case '1:1': {
                const class6 = defaultClass + '6';
                const classArray = leftSplitterPane.appearance.class.split(' ');
                const colClassItemIndex = classArray.findIndex(c => c.startsWith(defaultClass));
                if (colClassItemIndex > -1) {
                    classArray[colClassItemIndex] = class6;
                } else {
                    classArray.unshift(class6);
                }
                leftSplitterPane.appearance.class = classArray.join(' ');

                break;

            }
            case '1:2': {
                const class4 = defaultClass + '4';
                const classArray = leftSplitterPane.appearance.class.split(' ');
                const colClassItemIndex = classArray.findIndex(c => c.startsWith(defaultClass));
                if (colClassItemIndex > -1) {
                    classArray[colClassItemIndex] = class4;
                } else {
                    classArray.unshift(class4);
                }
                leftSplitterPane.appearance.class = classArray.join(' ');

                break;
            }
        }

        // 移除右侧区域的宽度样式
        const rightclassArray = rightSplitterPane.appearance.class.split(' ');
        const rightColClassItemIndex = rightclassArray.findIndex(c => c.startsWith('f-col-w') || c.startsWith('f-col-h'));
        if (rightColClassItemIndex > -1) {
            rightclassArray.splice(rightColClassItemIndex, 1);
        }
        rightSplitterPane.appearance.class = rightclassArray.join(' ');

        this.notifyService.success('修改成功');
        this.refreshFormService.refreshFormDesigner.next();
    }



    /**
     * 限制布局方向菜单的使用范围
     * @param splitterId 当前分隔组件id
     * @param menuConfig 菜单配置
     */
    private assemblePaneDirectionMenu(splitterDocument: ComponentSchema, menuConfig: ControlContextMenuItem[]) {

        // 目前只支持两个面板的分隔组件
        if (!splitterDocument.contents || splitterDocument.contents.length !== 2) {
            // console.log('只支持包含2个分隔区域的面板启用布局方向菜单');
            menuConfig = menuConfig.filter(menu => menu.id !== SPLITTER_PANE_DIRECTION);
            return menuConfig;
        }
        // 限制可修改的范围
        // tslint:disable-next-line:max-line-length
        if (!splitterDocument.appearance || !splitterDocument.appearance.class || !splitterDocument.appearance.class.includes('f-page-content')) {
            // console.log('分隔组件必须包含f-page-content样式才能启用布局方向菜单');
            menuConfig = menuConfig.filter(menu => menu.id !== SPLITTER_PANE_DIRECTION);
            return menuConfig;
        }

        const leftSplitterPane = splitterDocument.contents[0];
        // tslint:disable-next-line:max-line-length
        if (!leftSplitterPane.appearance || !leftSplitterPane.appearance.class || !leftSplitterPane.appearance.class.includes('f-page-content-nav')) {
            // console.log('左侧分隔区域必须包含f-page-content-nav样式才能启用布局方向菜单');
            menuConfig = menuConfig.filter(menu => menu.id !== SPLITTER_PANE_DIRECTION);
            return menuConfig;
        }
        const rightSplitterPane = splitterDocument.contents[1];
        // tslint:disable-next-line:max-line-length
        if (!rightSplitterPane.appearance || !rightSplitterPane.appearance.class || !rightSplitterPane.appearance.class.includes('f-page-content-main')) {
            // console.log('右侧分隔组件必须包含f-page-content-main样式才能启用布局方向菜单');
            menuConfig = menuConfig.filter(menu => menu.id !== SPLITTER_PANE_DIRECTION);
            return menuConfig;
        }

        return menuConfig;
    }



    /**
     * 根据点击的菜单修改两侧面板的布局方向
     * @param splitterId 当前分隔组件id
     * @param command 比例菜单的command id
     */
    private setPaneDirection(splitterDocument: ComponentSchema, command: string) {
        let splitterClass = splitterDocument.appearance.class;

        const leftSplitterPane = splitterDocument.contents[0];
        const leftSplitterPaneClass = leftSplitterPane.appearance.class;

        const verticalClass = 'f-utils-flex-column';

        switch (command) {
            case SPLITTER_PANE_DIRECTION_HORIZONTAL: {
                // 1、面板移除纵向布局样式
                splitterClass = splitterClass.replace(verticalClass, '');
                splitterClass = splitterClass.replace('flex-column', '');
                splitterDocument.appearance.class = splitterClass;

                // 2、区域一增加横向宽度，移除纵向高度
                const w6Class = 'f-col-w6';
                const classArray = leftSplitterPaneClass.split(' ');
                const colClassItemIndex = classArray.findIndex(c => c.startsWith('f-col-h'));
                const wClassItemIndex = classArray.findIndex(c => c.startsWith('f-col-w'));
                if (colClassItemIndex > -1) {
                    classArray[colClassItemIndex] = w6Class;
                } else if (wClassItemIndex < 0) {
                    classArray.unshift(w6Class);
                }
                leftSplitterPane.appearance.class = classArray.join(' ');

                // 3、区域一修改拖动方向
                leftSplitterPane.resizeHandlers = 'e';

                break;
            }
            case SPLITTER_PANE_DIRECTION_VERTICAL: {
                // 1、面板增加纵向布局样式
                if (!splitterClass.includes(verticalClass)) {
                    splitterClass = splitterClass + ' ' + verticalClass;
                }
                splitterDocument.appearance.class = splitterClass;

                // 2、区域一增加纵向高度，移除横向宽度
                const h6Class = 'f-col-h6';
                const classArray = leftSplitterPaneClass.split(' ');
                const wClassItemIndex = classArray.findIndex(c => c.startsWith('f-col-w'));
                const hClassItemIndex = classArray.findIndex(c => c.startsWith('f-col-h'));
                if (wClassItemIndex > -1) {
                    classArray[wClassItemIndex] = h6Class;
                } else if (hClassItemIndex < 0) {
                    classArray.unshift(h6Class);
                }
                leftSplitterPane.appearance.class = classArray.join(' ');

                // 3、区域一修改拖动方向
                leftSplitterPane.resizeHandlers = 's';

                break;
            }
        }

        this.notifyService.success('修改成功');
        this.refreshFormService.refreshFormDesigner.next();
    }
    /**
     * 校验当前是否包含从表/从从表区域，从而控制右键菜单的显示项
     * @param containerId 右键的节点id
     * @param menuConfig 菜单配置
     */
    private assembleCreateChildContainerMenu(containerId: string, menuConfig: ControlContextMenuItem[]) {
        const templateOutlineSchema = this.domService.templateOutlineSchema || [];
        if (!templateOutlineSchema) {
            // console.log('未检测到模板配置数据');
            menuConfig = menuConfig.filter(menu =>
                menu.id !== CREATE_DETAIL_CONTAINER_COMMAND && menu.id !== CREATE_GRAND_CONTAINER_COMMAND);
            return menuConfig;
        }
        // tslint:disable-next-line:max-line-length
        const mainContainerSchema = templateOutlineSchema.find(schema => schema.type === 'RightMainContainer');

        if (!mainContainerSchema || !mainContainerSchema.children || mainContainerSchema.children.length < 1) {
            // console.log('未检测到右侧主区域配置数据');
            menuConfig = menuConfig.filter(menu =>
                menu.id !== CREATE_DETAIL_CONTAINER_COMMAND && menu.id !== CREATE_GRAND_CONTAINER_COMMAND);
            return menuConfig;
        }

        const rootCmp = this.domService.getComponentById('root-component');

        const mainContainer = this.domService.getNodeByIdPath(rootCmp, mainContainerSchema.path as string);
        const likeCardCotainer = mainContainer.contents.find(co => co.type === DgControl.ContentContainer.type && co.isLikeCardContainer);
        let detailContainerParentElement;
        if (likeCardCotainer) {
            detailContainerParentElement = likeCardCotainer;
        } else {
            detailContainerParentElement = mainContainer;
        }

        if (detailContainerParentElement.id !== containerId) {
            // console.log('当前节点不是右侧主区域节点');
            menuConfig = menuConfig.filter(menu =>
                menu.id !== CREATE_DETAIL_CONTAINER_COMMAND && menu.id !== CREATE_GRAND_CONTAINER_COMMAND);
            return menuConfig;
        }

        // 判断是否包含从表区域
        const detailSchema = mainContainerSchema.children[1];
        const detailSectionContainer = this.domService.getNodeByIdPath(rootCmp, detailSchema.path as string);
        const hasDetailContainer = !!detailSectionContainer && detailSchema.id === 'child-grid';

        if (hasDetailContainer) {
            // 存在从表区域
            menuConfig = menuConfig.filter(menu => menu.id !== CREATE_DETAIL_CONTAINER_COMMAND);

            if (mainContainerSchema.children.length > 2) {
                const grandsonSchema = mainContainerSchema.children[2];
                const grandsonSectionContainer = this.domService.getNodeByIdPath(rootCmp, grandsonSchema.path as string);
                const hasGrandsonDetailContainer = !!grandsonSectionContainer && grandsonSchema.id === 'grandson-grid';
                if (hasGrandsonDetailContainer) {
                    // 存在从从表区域
                    menuConfig = menuConfig.filter(menu => menu.id !== CREATE_GRAND_CONTAINER_COMMAND);
                }
            } else {
                // schema中没有声明从从表区域，则不能创建从从表区域
                menuConfig = menuConfig.filter(menu => menu.id !== CREATE_GRAND_CONTAINER_COMMAND);
            }

        } else {
            // 不存在从表区域，则不能创建从从表区域
            menuConfig = menuConfig.filter(menu => menu.id !== CREATE_GRAND_CONTAINER_COMMAND);
        }

        return menuConfig;
    }

    /**
     * 创建从表区域
     */
    private createDetailContainer() {
        const controlService = this.injector.get(ControlService);
        const createDetailService = new CreateDetailContainerService(this.domService, controlService);

        const templateOutlineSchema = this.domService.templateOutlineSchema || [];
        const mainContainerSchema = templateOutlineSchema.find(schema =>
            schema.type === 'RightMainContainer');

        createDetailService.createDetailContainer(mainContainerSchema, 'child-grid');

        this.notifyService.success('已添加从表区域');
        this.refreshFormService.refreshFormDesigner.next();
    }

    /**
     * 创建从从表区域
     */
    private createGrandContainer() {
        const controlService = this.injector.get(ControlService);
        const createDetailService = new CreateDetailContainerService(this.domService, controlService);

        const templateOutlineSchema = this.domService.templateOutlineSchema || [];
        const mainContainerSchema = templateOutlineSchema.find(schema =>
            schema.type === 'MainContainer' || schema.type === 'RightMainContainer');

        createDetailService.createDetailContainer(mainContainerSchema, 'grandson-grid');

        this.notifyService.success('已添加从从表区域');
        this.refreshFormService.refreshFormDesigner.next();
    }

    /**
     * 组装子表填充菜单
     * @param containerId 右侧区域SplitterPane 的id
     * @param menuConfig 菜单
     */
    private assembleChildFillMenu(containerId: string, menuConfig: ControlContextMenuItem[]): ControlContextMenuItem[] {

        const splitterPane = this.cmpInstance.component.contents.find(co => co.id === containerId);
        if (!splitterPane) {
            menuConfig = menuConfig.filter(menu => menu.id !== CHILD_FILL_COMMAND);
            return menuConfig;
        }
        // 限定右侧主区域
        const className = splitterPane.appearance && splitterPane.appearance.class;
        if (!className || !className.includes('f-page-content-main')) {
            menuConfig = menuConfig.filter(menu => menu.id !== CHILD_FILL_COMMAND);
            return menuConfig;
        }

        // 收集子表区域
        const childContainerServ = new ChildContainerFillService(this.injector, this.cmpInstance);
        const childContainers = childContainerServ.getChildContainers(splitterPane);
        if (!childContainers.length) {
            menuConfig = menuConfig.filter(menu => menu.id !== CHILD_FILL_COMMAND);
            return menuConfig;
        }

        // 判断当前是否已启用填充
        const childFillMenu = menuConfig.find(menu => menu.id === CHILD_FILL_COMMAND);
        childFillMenu.title = (className.includes('f-page-child-fill') ? '关闭' : '启用') + childFillMenu.title;
        childFillMenu.id = (className.includes('f-page-child-fill') ? 'close' : 'enable') + childFillMenu.id;

        return menuConfig;
    }

    /**
     * 启用子表填充
     */
    private enableChildContainerFill(containerId: string) {
        const splitterPane = this.cmpInstance.component.contents.find(co => co.id === containerId);
        if (!splitterPane) {
            return;
        }
        const serv = new ChildContainerFillService(this.injector, this.cmpInstance);
        serv.enableChildContainerFill(splitterPane);

        this.refreshFormService.refreshFormDesigner.next();

    }
    /**
     * 关闭子表填充
     */
    private closeChildContainerFill(containerId: string) {
        const splitterPane = this.cmpInstance.component.contents.find(co => co.id === containerId);

        const serv = new ChildContainerFillService(this.injector, this.cmpInstance);
        serv.closeChildContainerFill(splitterPane);

        this.refreshFormService.refreshFormDesigner.next();
    }
}

